package com.mqtt.service.converter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * 协议转换器
 */
@Slf4j
@Component
public class ProtocolConverter {
    
    /**
     * 转换消息
     */
    public Map<String, Object> convert(String payload) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 尝试判断协议类型
            ProtocolType protocolType = detectProtocolType(payload);
            
            switch (protocolType) {
                case JSON:
                    result = convertJson(payload);
                    break;
                case HEX:
                    result = convertHex(payload);
                    break;
                case BASE64:
                    result = convertBase64(payload);
                    break;
                case CUSTOM:
                    result = convertCustom(payload);
                    break;
                default:
                    result = convertDefault(payload);
            }
            
            // 添加协议类型标识
            result.put("protocolType", protocolType.name());
            
        } catch (Exception e) {
            log.error("Error converting protocol", e);
            result.put("error", "Protocol conversion failed: " + e.getMessage());
            result.put("rawPayload", payload);
        }
        
        return result;
    }
    
    /**
     * 检测协议类型
     */
    private ProtocolType detectProtocolType(String payload) {
        // JSON格式检测
        if (isJson(payload)) {
            return ProtocolType.JSON;
        }
        
        // Base64格式检测
        if (isBase64(payload)) {
            return ProtocolType.BASE64;
        }
        
        // 十六进制格式检测
        if (isHex(payload)) {
            return ProtocolType.HEX;
        }
        
        // 默认为自定义格式
        return ProtocolType.CUSTOM;
    }
    
    /**
     * 转换JSON格式
     */
    private Map<String, Object> convertJson(String payload) {
        JSONObject json = JSON.parseObject(payload);
        Map<String, Object> result = new HashMap<>();
        
        // 标准化字段名称
        for (Map.Entry<String, Object> entry : json.entrySet()) {
            String key = standardizeFieldName(entry.getKey());
            Object value = convertValue(entry.getValue());
            result.put(key, value);
        }
        
        return result;
    }
    
    /**
     * 转换十六进制格式
     */
    private Map<String, Object> convertHex(String payload) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 移除空格
            String hex = payload.replaceAll("\\s+", "");
            
            // 转换为字节数组
            byte[] bytes = hexToBytes(hex);
            
            // 解析字节数组（根据具体协议定义）
            result = parseBytes(bytes);
            
        } catch (Exception e) {
            log.error("Error converting hex payload", e);
            result.put("hexData", payload);
        }
        
        return result;
    }
    
    /**
     * 转换Base64格式
     */
    private Map<String, Object> convertBase64(String payload) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // Base64解码
            byte[] decoded = Base64.getDecoder().decode(payload);
            
            // 尝试作为字符串处理
            String decodedStr = new String(decoded, StandardCharsets.UTF_8);
            
            // 如果解码后是JSON，递归处理
            if (isJson(decodedStr)) {
                return convertJson(decodedStr);
            }
            
            // 否则作为二进制数据处理
            result = parseBytes(decoded);
            
        } catch (Exception e) {
            log.error("Error converting base64 payload", e);
            result.put("base64Data", payload);
        }
        
        return result;
    }
    
    /**
     * 转换自定义格式
     */
    private Map<String, Object> convertCustom(String payload) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 假设自定义格式为: key1=value1;key2=value2;...
            String[] pairs = payload.split(";");
            for (String pair : pairs) {
                String[] keyValue = pair.split("=", 2);
                if (keyValue.length == 2) {
                    String key = standardizeFieldName(keyValue[0].trim());
                    String value = keyValue[1].trim();
                    result.put(key, convertValue(value));
                }
            }
        } catch (Exception e) {
            log.error("Error converting custom payload", e);
            result.put("rawData", payload);
        }
        
        return result;
    }
    
    /**
     * 默认转换
     */
    private Map<String, Object> convertDefault(String payload) {
        Map<String, Object> result = new HashMap<>();
        result.put("data", payload);
        result.put("timestamp", System.currentTimeMillis());
        return result;
    }
    
    /**
     * 解析字节数组
     */
    private Map<String, Object> parseBytes(byte[] bytes) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ByteBuffer buffer = ByteBuffer.wrap(bytes);
            
            // 示例协议解析
            // 假设协议格式：
            // [0-3]: 设备ID (int)
            // [4-7]: 时间戳 (int)
            // [8-11]: 温度 (float)
            // [12-15]: 湿度 (float)
            
            if (bytes.length >= 16) {
                int deviceId = buffer.getInt();
                int timestamp = buffer.getInt();
                float temperature = buffer.getFloat();
                float humidity = buffer.getFloat();
                
                result.put("deviceId", deviceId);
                result.put("timestamp", timestamp * 1000L); // 转换为毫秒
                result.put("temperature", temperature);
                result.put("humidity", humidity);
            } else {
                // 原始数据
                result.put("rawBytes", bytes);
                result.put("length", bytes.length);
            }
            
        } catch (Exception e) {
            log.error("Error parsing bytes", e);
            result.put("rawBytes", bytes);
        }
        
        return result;
    }
    
    /**
     * 标准化字段名称
     */
    private String standardizeFieldName(String fieldName) {
        // 转换为驼峰命名
        if (fieldName.contains("_")) {
            return toCamelCase(fieldName);
        }
        return fieldName;
    }
    
    /**
     * 转换值类型
     */
    private Object convertValue(Object value) {
        if (value instanceof String) {
            String strValue = (String) value;
            
            // 尝试转换为数字
            try {
                if (strValue.contains(".")) {
                    return Double.parseDouble(strValue);
                } else {
                    return Long.parseLong(strValue);
                }
            } catch (NumberFormatException e) {
                // 保持字符串类型
            }
            
            // 尝试转换为布尔值
            if ("true".equalsIgnoreCase(strValue) || "false".equalsIgnoreCase(strValue)) {
                return Boolean.parseBoolean(strValue);
            }
        }
        
        return value;
    }
    
    /**
     * 判断是否为JSON格式
     */
    private boolean isJson(String str) {
        try {
            JSON.parseObject(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 判断是否为Base64格式
     */
    private boolean isBase64(String str) {
        try {
            Base64.getDecoder().decode(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 判断是否为十六进制格式
     */
    private boolean isHex(String str) {
        return str.matches("^[0-9A-Fa-f\\s]+$") && str.length() % 2 == 0;
    }
    
    /**
     * 十六进制转字节数组
     */
    private byte[] hexToBytes(String hex) {
        int len = hex.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                    + Character.digit(hex.charAt(i + 1), 16));
        }
        return data;
    }
    
    /**
     * 下划线转驼峰
     */
    private String toCamelCase(String str) {
        StringBuilder result = new StringBuilder();
        boolean nextUpperCase = false;
        
        for (char c : str.toCharArray()) {
            if (c == '_') {
                nextUpperCase = true;
            } else {
                if (nextUpperCase) {
                    result.append(Character.toUpperCase(c));
                    nextUpperCase = false;
                } else {
                    result.append(Character.toLowerCase(c));
                }
            }
        }
        
        return result.toString();
    }
    
    /**
     * 协议类型枚举
     */
    private enum ProtocolType {
        JSON,
        HEX,
        BASE64,
        CUSTOM,
        UNKNOWN
    }
}